#include "ConsulCenter.h"

#include <workflow/WFTaskFactory.h>
#include <workflow/WFFacilities.h>
#include <workflow/HttpMessage.h>
#include <chrono>
#include <ppconsul/agent.h>
#include <memory>
#include <nlohmann/json.hpp>
#include <sstream>
#include <random>


using ppconsul::Consul;
using std::istringstream;
using namespace protocol;
using namespace ppconsul::agent;
using std::string;

namespace
{

    using json = nlohmann::json;


    //默认的注册中心访问url
    constexpr const char* DEFAULT_CONSUL_URL = "http://127.0.0.1:8500";
    //默认的数据中心名
    constexpr const char* DEFAULT_CONSUL_DC = "dc1";
    //最大重试次数
    constexpr const int RETRY_MAX = 3;
    //最大重定向次数
    constexpr const int REDIRECT_MAX = 3;

    size_t random_services(size_t max_idx) {

        // 使用 std::random_device 生成种子
        std::random_device rd{};
        unsigned seed = rd();

        // 初始化随机数引擎
        std::mt19937 generator(seed);

        // 创建分布（如均匀分布）
        std::uniform_int_distribution<int> dist(0, max_idx - 1);

        return dist(generator);
    }

    void handleQuery(string& address, unsigned short& port, bool& is_success, WFHttpTask* task) {

        // 任务失败: 及早失败原则
        if (task->get_state() != WFT_STATE_SUCCESS) {
            is_success = false;
#ifdef BUG
            std::cerr << "Error: " << WFGlobal::get_error_string(task->get_state(), task->get_error());
#endif
            return;
        }

        //利用返回值构造json数组
        const void* body;
        size_t len;
        task->get_resp()->get_parsed_body(&body, &len);
        json services = json::parse(static_cast<const char*>(body));
#ifdef BUG
        std::cout << "json: " << services.dump(2) << "\n";
#endif

        if (services.size() <= 0) {
            is_success = false;
            return;
        }
        //在能够使用的服务中随机取出一个服务的对象
        size_t idx = random_services(services.size());

        //从对象中解析出address和port
        address = services[idx]["Service"]["Address"];
        port = services[idx]["Service"]["Port"];

    }

}//end of anonymous namaspace


namespace l
{


    //根据服务名随机获取一个可用的服务的ip和端口
    bool ConsulCenter::get_address_and_port(const string& query_url, string& address, unsigned short& port) {

        WFFacilities::WaitGroup wg{ 1 };
        bool is_success = true;
        WFHttpTask* task = WFTaskFactory::create_http_task(query_url, RETRY_MAX, REDIRECT_MAX,
            std::bind(handleQuery, std::ref(address), std::ref(port), std::ref(is_success), std::placeholders::_1));

        SeriesWork* series = Workflow::create_series_work(task, [&wg](const SeriesWork*)
            {
                wg.done();
            });

        series->start();
        wg.wait();
        return is_success;
    }

    //利用通用url和服务名拼接出一个查询正常状态的服务
    void ConsulCenter::splice_url(string& url, const string& name) {
        url.append(name).append("?passing=true");
    }


}//end of namespace l


